package com.movie.service;

import com.movie.dto.NewsDTO;
import com.movie.dto.PageResponse;
import com.movie.entity.Category;
import com.movie.entity.News;
import com.movie.repository.NewsRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 资讯服务
 */
@Service
@RequiredArgsConstructor
public class NewsService {

    private final NewsRepository newsRepository;
    private final CategoryService categoryService;

    /**
     * 获取资讯列表
     */
    public PageResponse<NewsDTO> getNewsList(String category, Boolean isPublished, Boolean isTop, int page, int size, String sort) {
        Pageable pageable = PageRequest.of(page - 1, size, getSort(sort));
        Page<News> newsPage;

        // 构建动态查询条件
        if (category != null && !category.isEmpty()) {
            if (isPublished != null && isTop != null) {
                newsPage = newsRepository.findByCategoryNameAndIsPublishedAndIsTop(category, isPublished, isTop, pageable);
            } else if (isPublished != null) {
                newsPage = newsRepository.findByCategoryNameAndIsPublished(category, isPublished, pageable);
            } else if (isTop != null) {
                newsPage = newsRepository.findByCategoryNameAndIsTop(category, isTop, pageable);
            } else {
                newsPage = newsRepository.findByCategoryName(category, pageable);
            }
        } else {
            if (isPublished != null && isTop != null) {
                newsPage = newsRepository.findByIsPublishedAndIsTop(isPublished, isTop, pageable);
            } else if (isPublished != null) {
                newsPage = newsRepository.findByIsPublished(isPublished, pageable);
            } else if (isTop != null) {
                newsPage = newsRepository.findByIsTop(isTop, pageable);
            } else {
                newsPage = newsRepository.findAll(pageable);
            }
        }

        List<NewsDTO> newsList = newsPage.getContent().stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());

        PageResponse<NewsDTO> response = new PageResponse<>();
        response.setContent(newsList);
        response.setPage(newsPage.getNumber());
        response.setSize(newsPage.getSize());
        response.setTotalElements(newsPage.getTotalElements());
        response.setTotalPages(newsPage.getTotalPages());
        response.setHasPrevious(newsPage.hasPrevious());
        response.setHasNext(newsPage.hasNext());
        return response;
    }

    /**
     * 获取资讯详情
     */
    public NewsDTO getNewsDetail(Long id) {
        News news = newsRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("资讯不存在"));

        if (!news.getIsPublished()) {
            throw new RuntimeException("资讯未发布");
        }

        // 增加浏览量
        news.setViewCount(news.getViewCount() + 1);
        newsRepository.save(news);

        return convertToDTO(news);
    }

    /**
     * 搜索资讯
     */
    public PageResponse<NewsDTO> searchNews(String keyword, int page, int size) {
        // 参数容错：页码最小为1，size最小为1（默认10）
        int safePage = Math.max(1, page);
        int safeSize = size <= 0 ? 10 : size;
        Pageable pageable = PageRequest.of(safePage - 1, safeSize, Sort.by(Sort.Direction.DESC, "publishTime"));

        // 关键词处理：去除首尾空白，空关键词则返回最新已发布列表
        String safeKeyword = keyword == null ? "" : keyword.trim();
        Page<News> newsPage = safeKeyword.isEmpty()
                ? newsRepository.findByIsPublishedTrueOrderByPublishTimeDesc(pageable)
                : newsRepository.searchByTitle(safeKeyword, pageable);

        List<NewsDTO> newsList = newsPage.getContent().stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());

        PageResponse<NewsDTO> response = new PageResponse<>();
        response.setContent(newsList);
        response.setPage(newsPage.getNumber());
        response.setSize(newsPage.getSize());
        response.setTotalElements(newsPage.getTotalElements());
        response.setTotalPages(newsPage.getTotalPages());
        response.setHasPrevious(newsPage.hasPrevious());
        response.setHasNext(newsPage.hasNext());
        return response;
    }

    /**
     * 获取热门资讯
     */
    public List<NewsDTO> getHotNews(int limit) {
        Pageable pageable = PageRequest.of(0, limit, Sort.by(Sort.Direction.DESC, "viewCount"));
        Page<News> newsPage = newsRepository.findByIsPublishedTrueOrderByViewCountDesc(pageable);

        return newsPage.getContent().stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }

    /**
     * 获取置顶资讯
     */
    public List<NewsDTO> getTopNews() {
        List<News> topNews = newsRepository.findByIsTopTrueAndIsPublishedTrueOrderByPublishTimeDesc();
        return topNews.stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }

    /**
     * 获取最新资讯
     */
    public List<NewsDTO> getLatestNews(int limit) {
        Pageable pageable = PageRequest.of(0, limit, Sort.by(Sort.Direction.DESC, "publishTime"));
        Page<News> newsPage = newsRepository.findByIsPublishedTrueOrderByPublishTimeDesc(pageable);

        return newsPage.getContent().stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
    }

    private Sort getSort(String sort) {
        switch (sort) {
            case "view":
                return Sort.by(Sort.Direction.DESC, "viewCount");
            case "like":
                return Sort.by(Sort.Direction.DESC, "likeCount");
            default:
                return Sort.by(Sort.Direction.DESC, "publishTime");
        }
    }

    /**
     * 创建资讯
     */
    public NewsDTO createNews(NewsDTO newsDTO) {
        News news = new News();
        news.setTitle(newsDTO.getTitle());
        news.setContent(newsDTO.getContent());
        news.setCoverImage(newsDTO.getCoverImage());
        
        // 设置分类
        if (newsDTO.getCategory() != null && !newsDTO.getCategory().isEmpty()) {
            Category category = categoryService.findByName(newsDTO.getCategory());
            if (category == null) {
                throw new RuntimeException("分类不存在: " + newsDTO.getCategory());
            }
            news.setCategory(category);
        }
        
        news.setIsPublished(newsDTO.getIsPublished() != null ? newsDTO.getIsPublished() : false);
        news.setIsTop(newsDTO.getIsTop() != null ? newsDTO.getIsTop() : false);
        
        // 如果设置为发布状态，设置发布时间
        if (news.getIsPublished()) {
            news.setPublishTime(java.time.LocalDateTime.now());
        }
        
        News savedNews = newsRepository.save(news);
        return convertToDTO(savedNews);
    }

    /**
     * 更新资讯
     */
    public NewsDTO updateNews(Long id, NewsDTO newsDTO) {
        News news = newsRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("资讯不存在"));
        
        news.setTitle(newsDTO.getTitle());
        news.setContent(newsDTO.getContent());
        news.setCoverImage(newsDTO.getCoverImage());
        
        // 设置分类
        if (newsDTO.getCategory() != null && !newsDTO.getCategory().isEmpty()) {
            Category category = categoryService.findByName(newsDTO.getCategory());
            if (category == null) {
                throw new RuntimeException("分类不存在: " + newsDTO.getCategory());
            }
            news.setCategory(category);
        }
        
        boolean wasPublished = news.getIsPublished();
        news.setIsPublished(newsDTO.getIsPublished() != null ? newsDTO.getIsPublished() : false);
        news.setIsTop(newsDTO.getIsTop() != null ? newsDTO.getIsTop() : false);
        
        // 如果从草稿变为发布状态，设置发布时间
        if (!wasPublished && news.getIsPublished()) {
            news.setPublishTime(java.time.LocalDateTime.now());
        }
        
        News updatedNews = newsRepository.save(news);
        return convertToDTO(updatedNews);
    }

    /**
     * 删除资讯
     */
    public void deleteNews(Long id) {
        News news = newsRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("资讯不存在"));
        newsRepository.delete(news);
    }

    /**
     * 更新资讯状态
     */
    public NewsDTO updateNewsStatus(Long id, Boolean status) {
        News news = newsRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("资讯不存在"));
        
        news.setIsPublished(status);
        
        // 如果设置为发布状态，设置发布时间
        if (status && news.getPublishTime() == null) {
            news.setPublishTime(java.time.LocalDateTime.now());
        }
        
        News updatedNews = newsRepository.save(news);
        return convertToDTO(updatedNews);
    }

    /**
     * 设置置顶状态
     */
    public NewsDTO setTopNews(Long id, Boolean isTop) {
        News news = newsRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("资讯不存在"));
        
        news.setIsTop(isTop);
        News updatedNews = newsRepository.save(news);
        return convertToDTO(updatedNews);
    }

    private NewsDTO convertToDTO(News news) {
        NewsDTO dto = new NewsDTO();
        dto.setId(news.getId());
        dto.setTitle(news.getTitle());
        dto.setContent(news.getContent());
        dto.setCoverImage(news.getCoverImage());
        Category category = news.getCategory();
        if (category != null) {
            dto.setCategory(category.getName());
        }
        dto.setViewCount(news.getViewCount());
        dto.setLikeCount(news.getLikeCount());
        dto.setIsPublished(news.getIsPublished());
        dto.setIsTop(news.getIsTop());
        dto.setPublishTime(news.getPublishTime());
        dto.setCreateTime(news.getCreateTime());
        dto.setUpdateTime(news.getUpdateTime());
        return dto;
    }
}